package wcg;

import ikelib.FileDropTarget;
import ikelib.Spline;
import ikelib.wintime;

import java.awt.GridBagLayout;
import javax.swing.JPanel;
import java.awt.Dimension;
import javax.swing.JScrollPane;
import java.awt.Rectangle;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.TreeSet;

import javax.swing.ImageIcon;
import javax.swing.JFileChooser;
import javax.swing.JTable;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.JButton;
import javax.swing.filechooser.FileNameExtensionFilter;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;

import checkerView.CheckerView;

public class PanelSplineInterporation extends JPanel {

	private static final long serialVersionUID = 1L;
	private JLabel jLabelInput = null;
	private JLabel jLabelOutTime = null;
	private JButton jButtonDo = null;
	private JLabel jLabelMeasureTime = null;
	private JTextField jTextFieldMesurementTime = null;
	private JLabel jLabelTitle = null;
	private JLabel jLabel = null;
	private JTextField jTextFieldDifferece = null;
	private JLabel jLabelPicture = null;
	private JButton jButtonOpenFile = null;
	public  CheckerView mCheckerView = null;
	private JCheckBox jCheckBoxMeasuring2True = null;
	private boolean mIsMeasure2True = false;
	private JComboBox jComboBoxTableFile = null; 
	private JComboBox jComboBoxDesiredTime = null; 

	/**
	 * This is the default constructor
	 */
	public PanelSplineInterporation() {
		super();
		initialize();
	}

	/**
	 * This method initializes this
	 * 
	 * @return void
	 */
	private void initialize() {
		jLabelPicture = new JLabel();
		jLabelPicture.setBounds(new Rectangle(8, 26, 210, 198));
		jLabelPicture.setIcon(new ImageIcon(getClass().getClassLoader().getResource("images/NaturalCubicSpline.PNG")));
		jLabelPicture.setText("");
		jLabel = new JLabel();
		jLabel.setBounds(new Rectangle(234, 198, 152, 19));
		jLabel.setText("(B)-(A)Different [s]");
		jLabelTitle = new JLabel();
		jLabelTitle.setBounds(new Rectangle(16, 0, 758, 24));
		jLabelTitle.setText("The Spline Interporation tool calculate the corrected measurement time using Natural Cubic Spline , liner or simple offset. ");
		jLabelMeasureTime = new JLabel();
		jLabelMeasureTime.setBounds(new Rectangle(233, 164, 148, 23));
		jLabelMeasureTime.setText("(B) Measurement time");
		jLabelOutTime = new JLabel();
		jLabelOutTime.setBounds(new Rectangle(234, 107, 139, 18));
		jLabelOutTime.setText("(A) Desired tme.");
		jLabelInput = new JLabel();
		jLabelInput.setBounds(new Rectangle(232, 55, 294, 21));
		jLabelInput.setText("Time table file.(True time,Measurement time)");
		this.setSize(782, 241);
		this.setLayout(null);
		this.add(jLabelInput, null);
		this.add(jLabelOutTime, null);
		this.add(getJButtonDo(), null);
		this.add(jLabelMeasureTime, null);
		this.add(getJTextFieldMesurementTime(), null);
		this.add(jLabelTitle, null);
		this.add(jLabel, null);
		this.add(getJTextFieldDifferece(), null);
		this.add(jLabelPicture, null);
		this.add(getJButtonOpenFile(), null);  // Generated
		this.add(getJCheckBoxMeasuring2True(), null);  // Generated
		this.add(getJComboBoxTableFile(), null);  // Generated
		this.add(getJComboBoxDesiredTime(), null);  // Generated
		this.add(getJButtonEditTableFileName(), null);  // Generated
	}

	/**
	 * 
	 */
	private void doCalc(){
		boolean calcReverse = mIsMeasure2True = jCheckBoxMeasuring2True.isSelected();
		jTextFieldMesurementTime.setText("");
		jTextFieldDifferece.setText("");
		String tablefile = (String)jComboBoxTableFile.getSelectedItem();
		// 時刻
		String tt = (String)jComboBoxDesiredTime.getSelectedItem();
		// コンボボックスに追加
		jComboBoxDesiredTime.insertItemAt(tt, 0);
		// 重複の場合、過去のデータを消す
		for(int i=1;i<jComboBoxDesiredTime.getItemCount();i++){
			String sss = (String)jComboBoxDesiredTime.getItemAt(i);
			if(tt.compareToIgnoreCase(sss)==0){
				jComboBoxDesiredTime.removeItemAt(i);
			}
		}
		jComboBoxDesiredTime.setSelectedItem(tt);
		
		wintime ttwin = new wintime();
		try {
			ttwin.parseDaySec(tt);
			double ttdouble = (double)ttwin.getValueU();
			
			File f = new File(tablefile);
			FileReader fr;
			fr = new FileReader(f);
			BufferedReader r = new BufferedReader(fr);
			String str=null;
			
			// 最初にソートする
			System.out.println("Reading Time Table...\n"+tablefile); 
			TreeSet<String> data = new TreeSet<String>(); 
			int linecount=0;
			while( (str = r.readLine()) != null){
				str = str.replaceAll("//.*", "");
				str = str.trim();
				String[] tok = str.split(",");
				if(tok.length<2) continue;
				data.add(str);
				linecount++;
				System.out.println(str);
			}
			System.out.println(String.format(" %d line read and sorted.",linecount));
			if(linecount<=0){
				System.err.println("Error not table data");
				return ;
			}
			ArrayList<Double> realtime = new ArrayList<Double>();
			ArrayList<Double> meastime = new ArrayList<Double>();
			System.out.println("Processing Time Table... \n(1)True , (2)Measurement time , (2)-(1) difference[s] "); 
			Iterator<String> ite = data.iterator();
			while(ite.hasNext()){
				str = ite.next();
				String[] tok = str.split(",");
				if(tok.length<2) continue;
				wintime wtr = new wintime();
				if(3!=wtr.parseDaySec(tok[0])){
					System.err.println(" Error Time format : "+tok[0]);
					return;
				}
				double rus = (double)wtr.getValueU();
				realtime.add(rus);
				wintime wtm = new wintime();
				if(3!=wtm.parseDaySec(tok[1])){
					System.err.println(" Error Time format : "+tok[1]);
					return;
				}
				double mus = (double)wtm.getValueU();
				
				meastime.add(mus);
				//	String mes = wtr.fmtDay() + " " + wtr.fmtuSec()+ " , " +  wtm.fmtDay() + " " + wtm.fmtuSec();
				String mes = wtr.fmtFull() + " , " + wtm.fmtFull();
				mes += String.format(" , %,f",(mus-rus)/1e6);
				System.out.println(mes);
			}
			double[] rt  =new double[realtime.size()];
			double[] mt  =new double[realtime.size()];
			for(int idx = 0;idx<realtime.size();idx++){
				if(!calcReverse){
					rt[idx] = realtime.get(idx);
					mt[idx] = meastime.get(idx);
				}
				else{
					mt[idx] = realtime.get(idx);
					rt[idx] = meastime.get(idx);
				}
			}
			
			double measdouble = 0.0;
			if(rt.length>=3){
				// 範囲チェック
				//
				if(rt[0]>ttdouble || rt[rt.length-1] < ttdouble){
					System.err.println("Error time range");
					return;
				}
				System.out.println("\nCalculate spline interpolation ...\n(A) , (B)");
				Spline s = new Spline(rt, mt);
				measdouble = s.map(ttdouble);
			}
			else if(rt.length==2){
				if(rt[0]==rt[1]){
					System.err.println("Error table data (true time0=true time1)");
					return;
				}
				System.out.println("\nWarnning : Calculate liner interpolation ...\n(A) , (B) ");
				LinerInterpolate l = new LinerInterpolate(rt[0],mt[0],rt[1],mt[1]);
				measdouble = l.get(ttdouble);
			}
			else if(rt.length==1){
				if(rt[0]==0.0){
					System.err.println("Error table data (true time0=0.0)");
					return;
				}
				System.out.println("\nWarnning : Calculate simple offset ...\n(A) , (B) ");
				LinerInterpolate l = new LinerInterpolate(rt[0],mt[0]);
				measdouble = l.get(ttdouble);
			}
			else{
				System.err.println("Error table data");
				return;
			}
			
			wintime measwt = new wintime(measdouble);
			String outstr = measwt.fmtFull();
			jTextFieldMesurementTime.setText(outstr);
			double deltasec = (measdouble-ttwin.getValueU())/1e6;
			jTextFieldDifferece.setText(String.format("%,f",deltasec));
			
			String mes = ttwin.fmtFull() + " , " + measwt.fmtFull();
			mes += String.format(" , %,f",deltasec);
			System.out.println(mes);
			
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch(NumberFormatException e){
			e.printStackTrace();
		}
		
	}

	/**
	 * This method initializes jButtonDo	
	 * 	
	 * @return javax.swing.JButton	
	 */
	private JButton getJButtonDo() {
		if (jButtonDo == null) {
			jButtonDo = new JButton();
			jButtonDo.setBounds(new Rectangle(421, 137, 93, 21));
			jButtonDo.setText("Calculate");
			jButtonDo.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
					if(mCheckerView!=null){
						mCheckerView.ResetContents();
					}
					doCalc();
				}
			});
		}
		return jButtonDo;
	}

	/**
	 * This method initializes jTextFieldMesurementTime	
	 * 	
	 * @return javax.swing.JTextField	
	 */
	private JTextField getJTextFieldMesurementTime() {
		if (jTextFieldMesurementTime == null) {
			jTextFieldMesurementTime = new JTextField();
			jTextFieldMesurementTime.setEditable(false);
			jTextFieldMesurementTime.setBounds(new Rectangle(395, 163, 182, 26));
		}
		return jTextFieldMesurementTime;
	}

	/**
	 * This method initializes jTextFieldDifferece	
	 * 	
	 * @return javax.swing.JTextField	
	 */
	private JTextField getJTextFieldDifferece() {
		if (jTextFieldDifferece == null) {
			jTextFieldDifferece = new JTextField();
			jTextFieldDifferece.setEditable(false);
			jTextFieldDifferece.setBounds(new Rectangle(395, 194, 180, 26));
		}
		return jTextFieldDifferece;
	}

	/**
	 * This method initializes jButtonOpenFile	
	 * 	
	 * @return javax.swing.JButton	
	 */
	private JButton getJButtonOpenFile() {
		if (jButtonOpenFile == null) {
			jButtonOpenFile = new JButton();
			jButtonOpenFile.setBounds(new Rectangle(680, 53, 22, 22));  // Generated
			//jButtonOpenFile.setText("...");  // Generated
			jButtonOpenFile.setIcon(new ImageIcon(getClass().getClassLoader().getResource("images/folder_page.png")));
			jButtonOpenFile.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
					JComboBox cb = jComboBoxTableFile;
					String orgfile = (String)cb.getSelectedItem();
					JFileChooser filechooser = new JFileChooser(orgfile);//@
					filechooser.setFileSelectionMode( JFileChooser.FILES_ONLY);
					filechooser.setDialogTitle("Open Time Table file");
					FileNameExtensionFilter filter = new FileNameExtensionFilter("Time Table file(.txt)", "txt");
					filechooser.addChoosableFileFilter(filter);
					int selected = filechooser.showOpenDialog(jButtonOpenFile);
					File file = null;
					if ( selected == JFileChooser.APPROVE_OPTION ) {
						file = filechooser.getSelectedFile ();
						String fname = file.getAbsolutePath();
						
						cb.insertItemAt(fname,0);
						cb.getModel().setSelectedItem(fname);
						for(int i=1;i<cb.getItemCount();i++){
							String str = (String)cb.getItemAt(i);
							if(fname.compareToIgnoreCase(str)==0){
								cb.removeItemAt(i);
							}
						}
						cb.getModel().setSelectedItem(fname);
					}
				}
			});
		}
		return jButtonOpenFile;
	}

	/**
	 * This method initializes jCheckBoxMeasuring2True	
	 * 	
	 * @return javax.swing.JCheckBox	
	 */
	private JCheckBox getJCheckBoxMeasuring2True() {
		if (jCheckBoxMeasuring2True == null) {
			jCheckBoxMeasuring2True = new JCheckBox();
			jCheckBoxMeasuring2True.setBounds(new Rectangle(400, 105, 150, 22));  // Generated
			jCheckBoxMeasuring2True.setText("Measurement to True");  // Generated
			jCheckBoxMeasuring2True.addItemListener(new java.awt.event.ItemListener() {
				public void itemStateChanged(java.awt.event.ItemEvent e) {
					mIsMeasure2True = jCheckBoxMeasuring2True.isSelected();
					if(mIsMeasure2True){
						jLabelPicture.setIcon(new ImageIcon(getClass().getClassLoader().getResource("images/NaturalCubicSplineRev.PNG")));
					}
					else{
						jLabelPicture.setIcon(new ImageIcon(getClass().getClassLoader().getResource("images/NaturalCubicSpline.PNG")));
					}
				}
			});
		}
		return jCheckBoxMeasuring2True;
	}
	/**
	 * プロパティのセーブ、ロード
	 * @param save
	 * @param prop
	 */
	private static String FmtTableFiles = "TableFile";  //  @jve:decl-index=0:
	private static String FmtDesiredTime = "DesiredTime";  //  @jve:decl-index=0:
	private JButton jButtonEditTableFileName = null;
	public void LoadSaveProperty(boolean save,winchkgProp prop){
		if(save){
			JComboBox c = jComboBoxTableFile;//@
			for(int i=0;i<c.getItemCount() && i<16;i++){
				String str = (String)c.getItemAt(i);
				String key = FmtTableFiles + String.format("%d",i);
				prop.setString(key , str);
			}
			
			c = jComboBoxDesiredTime;//@
			for(int i=0;i<c.getItemCount() && i<16;i++){
				String str = (String)c.getItemAt(i);
				String key = FmtDesiredTime + String.format("%d",i);
				prop.setString(key , str);
			}
		}
		else{
			for(int i=0;i<16;i++){
				String key = FmtTableFiles + String.format("%d",i);
				String dat = prop.getString(key,"");
				if(!dat.isEmpty()){
					jComboBoxTableFile.addItem(dat);
				}
				key = FmtDesiredTime + String.format("%d",i);
				dat = prop.getString(key,"");
				if(!dat.isEmpty()){
					jComboBoxDesiredTime.addItem(dat);
				}
				
			}
//			int colormode = prop.getInt(FmtTimeChartColor,0);
//			setColorMode(colormode);
//			boolean b = prop.getBoolean(FmtShowMean,true);
//			setShowChannelInfo(b);
//			GraphAreaXOffset = prop.getInt(FmtGraphicX,250);
		}

	}

	/**
	 * This method initializes jComboBoxTableFile	
	 * 	
	 * @return javax.swing.JComboBox	
	 */
	private JComboBox getJComboBoxTableFile() {
		if (jComboBoxTableFile == null) {
			jComboBoxTableFile = new JComboBox();
			//jComboBoxTableFile.setEditable(true);
			jComboBoxTableFile.setDropTarget(new FileDropTarget());
			jComboBoxTableFile.setBounds(new Rectangle(231, 78, 470, 22));  // Generated
		}
		return jComboBoxTableFile;
	}

	/**
	 * This method initializes jComboBoxDesiredTime	
	 * 	
	 * @return javax.swing.JComboBox	
	 */
	private JComboBox getJComboBoxDesiredTime() {
		if (jComboBoxDesiredTime == null) {
			jComboBoxDesiredTime = new JComboBox();
			jComboBoxDesiredTime.setEditable(true);
			jComboBoxDesiredTime.setBounds(new Rectangle(231, 134, 177, 23));  // Generated
		}
		return jComboBoxDesiredTime;
	}

	/**
	 * This method initializes jButtonEditTableFileName	
	 * 	
	 * @return javax.swing.JButton	
	 */
	private JButton getJButtonEditTableFileName() {
		if (jButtonEditTableFileName == null) {
			jButtonEditTableFileName = new JButton();
			jButtonEditTableFileName.setIcon(new ImageIcon(getClass().getClassLoader().getResource("images/pencil.png")));
			jButtonEditTableFileName.setBounds(new Rectangle(650, 54, 22, 22));  // Generated
			jButtonEditTableFileName.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
					if(jComboBoxTableFile.isEditable()){
						jComboBoxTableFile.setEditable(false);
					}
					else{
						jComboBoxTableFile.setEditable(true);
					}
				}
			});
		}
		return jButtonEditTableFileName;
	}
}  //  @jve:decl-index=0:visual-constraint="17,10"
